// ===============================================
// dynamic_height_grid_view
// 魔改 List 实现 GridView 效果 目的是为了能够 动态高度
// 使用分帧技术实现
// Create by Will on 16/9/2023 13:18
// Copyright Will .All rights reserved.
// ===============================================

import 'package:flutter/material.dart';
import 'package:keframe/keframe.dart';

class DynamicHeightGrid {
  DynamicHeightGrid._internal();

  static Widget dynamicHeightGridView({
    Key? key,
    //编辑的子
    required IndexedWidgetBuilder builder,
    //返回多少个
    required int itemCount,
    //每一行多少个
    required int crossAxisCount,
    //默认的行间距
    double crossAxisSpacing = 8,
    //默认的横间距
    double mainAxisSpacing = 8,
    //对齐方式
    CrossAxisAlignment rowCrossAxisAlignment = CrossAxisAlignment.start,
    //控制器的名称
    ScrollController? controller,
    //是否采用不滚动
    bool shrinkWrap = false,
    //滚动的开关
    ScrollPhysics? physics,
    //预加载的图
    Widget? placeHolder,
    //头部
    Widget? header,
    //列表预加载的高度
    double cacheExtent = 500,
    //外间距
    EdgeInsetsGeometry? padding,
    //是否使用分帧
    bool useFraming = true,
    //滚动分享
    Axis? scrollDirection = Axis.vertical,
  }) {
    int columnLength() {
      if (itemCount % crossAxisCount == 0) {
        return itemCount ~/ crossAxisCount;
      } else {
        return (itemCount ~/ crossAxisCount) + 1;
      }
    }

    //这里应该给他保留原滋原味的滑动事件
    return ListView.builder(
      key: key,
      padding: padding,
      shrinkWrap: shrinkWrap,
      physics: physics,
      cacheExtent: cacheExtent,
      controller: controller,
      itemBuilder: (ctx, columnIndex) {
        if (header != null && columnIndex == 0) {
          return header;
        }
        return _GridRow(
          columnIndex: columnIndex - (header != null ? 1 : 0),
          builder: builder,
          itemCount: itemCount,
          crossAxisCount: crossAxisCount,
          crossAxisSpacing: crossAxisSpacing,
          mainAxisSpacing: mainAxisSpacing,
          crossAxisAlignment: rowCrossAxisAlignment,
          placeHolder: placeHolder,
          // useCache: useCache,
        );
      },
      itemCount: columnLength() + (header != null ? 1 : 0),
    );
  }

  static Widget sliverDynamicHeightGridView({
    Key? key,
    //编辑的子
    required IndexedWidgetBuilder builder,
    //返回多少个
    required int itemCount,
    //每一行多少个
    required int crossAxisCount,
    //默认的行间距
    double crossAxisSpacing = 8,
    //默认的横间距
    double mainAxisSpacing = 8,
    //对齐方式
    CrossAxisAlignment rowCrossAxisAlignment = CrossAxisAlignment.start,
    //控制器的名称
    ScrollController? controller,
    //是否采用不滚动
    bool shrinkWrap = false,
    //滚动的开关
    ScrollPhysics? physics,
    //预加载的图
    Widget? placeHolder,
    //列表预加载的高度
    double cacheExtent = 500,
    //外间距
    EdgeInsetsGeometry? padding,
    //是否使用分帧
    bool useFraming = true,
  }) {
    int columnLength() {
      if (itemCount % crossAxisCount == 0) {
        return itemCount ~/ crossAxisCount;
      } else {
        return (itemCount ~/ crossAxisCount) + 1;
      }
    }

    return SliverList(
      delegate: SliverChildBuilderDelegate(
        (ctx, columnIndex) {
          return _GridRow(
            columnIndex: columnIndex,
            builder: builder,
            itemCount: itemCount,
            crossAxisCount: crossAxisCount,
            crossAxisSpacing: crossAxisSpacing,
            mainAxisSpacing: mainAxisSpacing,
            crossAxisAlignment: rowCrossAxisAlignment,
            placeHolder: placeHolder,
            useFraming: useFraming,
          );
        },
        childCount: columnLength(),
      ),
    );
  }
}

class _GridRow extends StatelessWidget {
  const _GridRow({
    required this.columnIndex,
    required this.builder,
    required this.itemCount,
    required this.crossAxisCount,
    required this.crossAxisSpacing,
    required this.mainAxisSpacing,
    required this.crossAxisAlignment,
    this.placeHolder,
    this.useFraming = false,
  });
  final IndexedWidgetBuilder builder;
  final int itemCount;
  final int crossAxisCount;
  final double crossAxisSpacing;
  final double mainAxisSpacing;
  final CrossAxisAlignment crossAxisAlignment;
  final int columnIndex;

  final Widget? placeHolder;

  //是否需要 分帧技术
  final bool useFraming;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.only(
        top: (columnIndex == 0) ? 0 : mainAxisSpacing,
      ),
      child: Row(
        crossAxisAlignment: crossAxisAlignment,
        mainAxisAlignment: MainAxisAlignment.start,
        children: List.generate(
          (crossAxisCount * 2) - 1,
          (rowIndex) {
            final rowNum = rowIndex + 1;
            if (rowNum.isEven) {
              return SizedBox(width: crossAxisSpacing);
            }
            final rowItemIndex = ((rowNum + 1) ~/ 2) - 1;
            final itemIndex = (columnIndex * crossAxisCount) + rowItemIndex;
            if (itemIndex > itemCount - 1) {
              return const Expanded(child: SizedBox());
            }
            return Expanded(
              child: useFraming
                  ? FrameSeparateWidget(
                      //预防与List 嵌套的时候 缓存冲突 所以+100000
                      index: 100000 + itemIndex,
                      // index: DateTime.now().millisecond,
                      placeHolder: placeHolder ??
                          Container(
                            color: Colors.black12,
                            height: 68,
                          ),
                      child: builder(context, itemIndex),
                    )
                  : builder(context, itemIndex),
            );
          },
        ),
      ),
    );
  }
}
